from ..errors import CardGameError, UnimplementedError

class ParserError(CardGameError):
    """
    Generated when malformed data is passed to 
    the parser.
    """
    pass

class ParserController(object):
    """
    Takes data from a ConnnectionsController and 
    translates it into function calls to a 
    GameController, then forms replies to the 
    ConnectionManager.
    """
    def __init__(self, game):
        """
        Usage: ParserController(game)
        'game' must be a GameController object.
        """
        pass
    
    def send_command(self, user_id, command):
        """
        Usage: send_command(user_id, "command_string")
        Takes a formatted string, parses it, 
        and calls the corresponding function(s) on 
        the GameController.
        
        Returns a tuple with either:
            True if the command was executed or 
            False if permission was denied,
            followed by a formatted response
        
        Throws an exception if the command was 
        incorrectly formatted.
        """
        raise UnimplementedError(self)
    
    def send_response(self, user_id, response):
        """
        Sends the supplied response back to the 
        CommunicationsController after being 
        properly formatted.
        
        This is used for unsolicited responses 
        (e.g. updates from other players)
        """
        raise UnimplementedError(self)

from pyparsing import Word, alphanums, Literal, CaselessLiteral, \
     ZeroOrMore, oneOf, Keyword, delimitedList

class SQLLikeParserController(ParserController):
    """
    A preliminary parser for a SQL-like protocol format.
    """
    def __init__(self, game, server):
        """
        Usage: SQLLikeParserController(game)
        'game' must be a GameController object.
        'server' must accept a fromParser(self, data) method 
        and call the toCommand(self, data) method.
        """
        self.game = game
        self.server = server
    
    def toCommand(self, data):
        object_name = Word(alphanums)
        object_type = oneOf("card deck table", caseless=True)
        object = object_name + Literal(".").suppress + object_type
        objects = delimitedList(object, ",")
        
        addStatement = Keyword("add", caseless=True)
        toToken = Keyword("to", caseless=True)
        command_add = addStatement + objects + toToken.suppress + objects
        
        tWord = Word(alphanums)
        test = tWord + tWord + "." + tWord + tWord + tWord + "." + tWord
                
        parse_results = test.parseString(data)
        
        if (parse_results):
            print parse_results
            self.server.fromParser("ADD:" + ";".join(parse_results))
        else:
            self.server.fromParser("Bad command.")